using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace SuperPongControl
{
    public class InputHandler
    {
        KeyboardState prevKb = new KeyboardState();
        MouseState prevMouse = new MouseState();
        Vector2 LastMouse = Vector2.Zero;

        public static Queue<Tuple<string, int>> movments = new Queue<Tuple<string, int>>();


        public List<SuperPongControl.Types.InputHandlerResultGameRuntime> handleKeyInputGameRunning(bool isCPU, bool Paused)
        {
            List<SuperPongControl.Types.InputHandlerResultGameRuntime> result = new List<Types.InputHandlerResultGameRuntime>();
            KeyboardState kb = Keyboard.GetState();
            MouseState mouse = Mouse.GetState();
            Vector2 currMouse = new Vector2(mouse.X, mouse.Y);

            //movments.Enqueue("1");
            


            if (!Paused)
            {
                if (isCPU)
                {
                    //  Player 1
                    if (kb.IsKeyDown(Keys.W))
                    {
                        result.Add(Types.InputHandlerResultGameRuntime.PlayerZeroUp);
                    }
                    else if (kb.IsKeyDown(Keys.S))
                    {
                        result.Add(Types.InputHandlerResultGameRuntime.PlayerZeroDown);
                    }
                    //  Player 2
                    if (kb.IsKeyDown(Keys.Up))
                    {
                        result.Add(Types.InputHandlerResultGameRuntime.PlayerZeroUp);
                    }
                    else if (kb.IsKeyDown(Keys.Down))
                    {
                        result.Add(Types.InputHandlerResultGameRuntime.PlayerZeroDown);
                    }
                }
                else
                {
                    //  Player 1
                    if (kb.IsKeyDown(Keys.Up))
                    {
                        result.Add(Types.InputHandlerResultGameRuntime.PlayerOneUp);
                    }
                    else if (kb.IsKeyDown(Keys.Down))
                    {
                        result.Add(Types.InputHandlerResultGameRuntime.PlayerOneDown);
                    }
                    //  Player 2
                    if (kb.IsKeyDown(Keys.W))
                    {
                        result.Add(Types.InputHandlerResultGameRuntime.PlayerZeroUp);
                    }
                    else if (kb.IsKeyDown(Keys.S))
                    {
                        result.Add(Types.InputHandlerResultGameRuntime.PlayerZeroDown);
                    }

                    while (movments.Count > 0)
                    {
                        Tuple<string, int> move = movments.Dequeue();
                        System.Console.WriteLine("Move is " + move.Item1 + " from Player " + move.Item2);
                         if (move.Item2 == 0)
                        {
                            if (move.Item1.Contains("LEFT"))
                            {
                                result.Add(Types.InputHandlerResultGameRuntime.PlayerZeroUp);
                                result.Add(Types.InputHandlerResultGameRuntime.PlayerZeroUp);
                                result.Add(Types.InputHandlerResultGameRuntime.PlayerZeroUp);
                            }
                            else if (move.Item1.Contains("RIGHT"))
                            {
                                result.Add(Types.InputHandlerResultGameRuntime.PlayerZeroDown);
                                result.Add(Types.InputHandlerResultGameRuntime.PlayerZeroDown);
                                result.Add(Types.InputHandlerResultGameRuntime.PlayerZeroDown);
                            }
                        }
                        else
                        {
                            if (move.Item1.Contains("LEFT"))
                            {
                                result.Add(Types.InputHandlerResultGameRuntime.PlayerOneUp);
                                result.Add(Types.InputHandlerResultGameRuntime.PlayerOneUp);
                                result.Add(Types.InputHandlerResultGameRuntime.PlayerOneUp);
                            }
                            else if (move.Item1.Contains("RIGHT"))
                            {
                                result.Add(Types.InputHandlerResultGameRuntime.PlayerOneDown);
                                result.Add(Types.InputHandlerResultGameRuntime.PlayerOneDown);
                                result.Add(Types.InputHandlerResultGameRuntime.PlayerOneDown);
                            }

                        }
                    }
                }
            }

            if (kb.IsKeyDown(Keys.P) && !prevKb.IsKeyDown(Keys.P))
            {
                result.Add(Types.InputHandlerResultGameRuntime.TogglePause);
            }
            if (kb.IsKeyDown(Keys.Escape) && !prevKb.IsKeyDown(Keys.Escape))
            {
                result.Add(Types.InputHandlerResultGameRuntime.GoToMainMenu);
            }
            this.LastMouse = currMouse;
            this.prevKb = kb;
            this.prevMouse = mouse;
            return result;
        }

        public Dictionary<SuperPongControl.Types.InputHandlerResultMainMenu, Object> handleKeyInputMainMenu()
        {
            Dictionary<Types.InputHandlerResultMainMenu, Object> result = new Dictionary<SuperPongControl.Types.InputHandlerResultMainMenu, Object>();
            KeyboardState kb = Keyboard.GetState();
            MouseState mouse = Mouse.GetState();
            Vector2 currMouse = new Vector2(mouse.X, mouse.Y);

            if (this.LastMouse != currMouse)
            {
                result.Add(Types.InputHandlerResultMainMenu.ProcessMouseMove, currMouse);
            }
            if ((mouse.LeftButton == ButtonState.Pressed) && (prevMouse.LeftButton == ButtonState.Released))
            {
                result.Add(Types.InputHandlerResultMainMenu.MainMenuProcessMouseClick, currMouse);
            }
            // Keyboard input
            if (kb.IsKeyDown(Keys.Up) && !prevKb.IsKeyDown(Keys.Up))
            {
                result.Add(Types.InputHandlerResultMainMenu.MainMenuUp, null);
            }
            if (kb.IsKeyDown(Keys.Down) && !prevKb.IsKeyDown(Keys.Down))
            {
                result.Add(Types.InputHandlerResultMainMenu.MainMenuDown, null);
            }
            if (kb.IsKeyDown(Keys.Enter) && !prevKb.IsKeyDown(Keys.Enter))
            {
                result.Add(Types.InputHandlerResultMainMenu.MainMenuSelect, null);
            }
            this.LastMouse = currMouse;
            this.prevKb = kb;
            this.prevMouse = mouse;
            return result;
        }

        public Dictionary<SuperPongControl.Types.InputHandlerResultInsCred, Object> handleKeyInputInsCred()
        {
            Dictionary<Types.InputHandlerResultInsCred, Object> result = new Dictionary<SuperPongControl.Types.InputHandlerResultInsCred, Object>();
            KeyboardState kb = Keyboard.GetState();
            MouseState mouse = Mouse.GetState();
            Vector2 currMouse = new Vector2(mouse.X, mouse.Y);

            if ((kb.IsKeyDown(Keys.Enter) || kb.IsKeyDown(Keys.Escape)) && !(prevKb.IsKeyDown(Keys.Enter) || prevKb.IsKeyDown(Keys.Escape)))
            {
                result.Add(Types.InputHandlerResultInsCred.BackMenuSelect, null);
            }
            if ((mouse.LeftButton == ButtonState.Pressed) && (prevMouse.LeftButton == ButtonState.Released))
            {
                result.Add(Types.InputHandlerResultInsCred.BackMenuProcessMouseClick, currMouse);
            }
            this.LastMouse = currMouse;
            this.prevKb = kb;
            this.prevMouse = mouse;
            return result;
        }

        public Dictionary<SuperPongControl.Types.InputHandlerResultNumPlayers, Object> handleKeyInputNumPlayers()
        {
            Dictionary<Types.InputHandlerResultNumPlayers, Object> result = new Dictionary<SuperPongControl.Types.InputHandlerResultNumPlayers, Object>();
            KeyboardState kb = Keyboard.GetState();
            MouseState mouse = Mouse.GetState();
            Vector2 currMouse = new Vector2(mouse.X, mouse.Y);

            if (kb.IsKeyDown(Keys.Up) && !prevKb.IsKeyDown(Keys.Up))
            {
                result.Add(Types.InputHandlerResultNumPlayers.NumPlayersMenuUp, null);
            }
            if (kb.IsKeyDown(Keys.Down) && !prevKb.IsKeyDown(Keys.Down))
            {
                result.Add(Types.InputHandlerResultNumPlayers.NumPlayersMenuDown, null);
            }
            if (this.LastMouse != currMouse)
            {
                result.Add(Types.InputHandlerResultNumPlayers.NumPlayersMenuProcessMouseMove, currMouse);
            }
            if ((mouse.LeftButton == ButtonState.Pressed) && (prevMouse.LeftButton == ButtonState.Released))
            {
                result.Add(Types.InputHandlerResultNumPlayers.BackMenuProcessMouseClick, currMouse);
                result.Add(Types.InputHandlerResultNumPlayers.NumPlayersMenuProcessMouseClick, currMouse);
            }
            if (kb.IsKeyDown(Keys.Enter) && !prevKb.IsKeyDown(Keys.Enter))
            {
                result.Add(Types.InputHandlerResultNumPlayers.NumPlayersMenuSelect, null);
            }
            if (kb.IsKeyDown(Keys.Escape) && !prevKb.IsKeyDown(Keys.Escape))
            {
                result.Add(Types.InputHandlerResultNumPlayers.BackMenuSelect, null);
            }
            this.LastMouse = currMouse;
            this.prevKb = kb;
            this.prevMouse = mouse;
            return result;
        }

        public Dictionary<SuperPongControl.Types.InputHandlerResultLifeSelect, Object> handleKeyInputLifeSelect()
        {
            Dictionary<Types.InputHandlerResultLifeSelect, Object> result = new Dictionary<SuperPongControl.Types.InputHandlerResultLifeSelect, Object>();
            KeyboardState kb = Keyboard.GetState();
            MouseState mouse = Mouse.GetState();
            Vector2 currMouse = new Vector2(mouse.X, mouse.Y);

            if (kb.IsKeyDown(Keys.Up) && !prevKb.IsKeyDown(Keys.Up))
            {
                result.Add(Types.InputHandlerResultLifeSelect.LifeSelectMenuUp, null);
            }
            if (kb.IsKeyDown(Keys.Down) && !prevKb.IsKeyDown(Keys.Down))
            {
                result.Add(Types.InputHandlerResultLifeSelect.LifeSelectMenuDown, null);
            }
            if (this.LastMouse != currMouse)
            {
                result.Add(Types.InputHandlerResultLifeSelect.LifeSelectMenuProcessMouseMove, currMouse);
            }
            if ((mouse.LeftButton == ButtonState.Pressed) && (prevMouse.LeftButton == ButtonState.Released))
            {
                result.Add(Types.InputHandlerResultLifeSelect.BackMenuProcessMouseClick, currMouse);
                result.Add(Types.InputHandlerResultLifeSelect.LifeSelectMenuProcessMouseClick, currMouse);
            }
            if (kb.IsKeyDown(Keys.Enter) && !prevKb.IsKeyDown(Keys.Enter))
            {
                result.Add(Types.InputHandlerResultLifeSelect.LifeSelectMenuSelect, null);
            }
            if (kb.IsKeyDown(Keys.Escape) && !prevKb.IsKeyDown(Keys.Escape))
            {
                result.Add(Types.InputHandlerResultLifeSelect.BackMenuSelect, null);
            }
            this.LastMouse = currMouse;
            this.prevKb = kb;
            this.prevMouse = mouse;
            return result;
        }

        public Dictionary<SuperPongControl.Types.InputHandlerResultDiff, Object> handleKeyInputDiff()
        {
            Dictionary<Types.InputHandlerResultDiff, Object> result = new Dictionary<SuperPongControl.Types.InputHandlerResultDiff, Object>();
            KeyboardState kb = Keyboard.GetState();
            MouseState mouse = Mouse.GetState();
            Vector2 currMouse = new Vector2(mouse.X, mouse.Y);

            if (kb.IsKeyDown(Keys.Up) && !prevKb.IsKeyDown(Keys.Up))
            {
                result.Add(Types.InputHandlerResultDiff.DiffMenuUp, null);
            }
            if (kb.IsKeyDown(Keys.Down) && !prevKb.IsKeyDown(Keys.Down))
            {
                result.Add(Types.InputHandlerResultDiff.DiffMenuDown, null);
            }
            if (this.LastMouse != currMouse)
            {
                result.Add(Types.InputHandlerResultDiff.DiffMenuProcessMouseMove, currMouse);
            }
            if ((mouse.LeftButton == ButtonState.Pressed) && (prevMouse.LeftButton == ButtonState.Released))
            {
                result.Add(Types.InputHandlerResultDiff.BackMenuProcessMouseClick, currMouse);
                result.Add(Types.InputHandlerResultDiff.DiffMenuProcessMouseClick, currMouse);
            }
            if (kb.IsKeyDown(Keys.Enter) && !prevKb.IsKeyDown(Keys.Enter))
            {
                result.Add(Types.InputHandlerResultDiff.DiffMenuSelect, null);
            }
            if (kb.IsKeyDown(Keys.Escape) && !prevKb.IsKeyDown(Keys.Escape))
            {
                result.Add(Types.InputHandlerResultDiff.BackMenuSelect, null);
            }
            this.LastMouse = currMouse;
            this.prevKb = kb;
            this.prevMouse = mouse;
            return result;
        }

        public Dictionary<SuperPongControl.Types.InputHandlerResultEnd, Object> handleKeyInputEnd()
        {
            Dictionary<Types.InputHandlerResultEnd, Object> result = new Dictionary<SuperPongControl.Types.InputHandlerResultEnd, Object>();
            KeyboardState kb = Keyboard.GetState();
            MouseState mouse = Mouse.GetState();
            Vector2 currMouse = new Vector2(mouse.X, mouse.Y);

            if (kb.IsKeyDown(Keys.Up) && !prevKb.IsKeyDown(Keys.Up))
            {
                result.Add(Types.InputHandlerResultEnd.EndMenuUp, null);
            }
            if (kb.IsKeyDown(Keys.Down) && !prevKb.IsKeyDown(Keys.Down))
            {
                result.Add(Types.InputHandlerResultEnd.EndMenuDown, null);
            }
            if (this.LastMouse != currMouse)
            {
                result.Add(Types.InputHandlerResultEnd.EndMenuProcessMouseMove, currMouse);
            }
            if ((mouse.LeftButton == ButtonState.Pressed) && (prevMouse.LeftButton == ButtonState.Released))
            {
                result.Add(Types.InputHandlerResultEnd.EndMenuProcessMouseClick, currMouse);
            }
            if (kb.IsKeyDown(Keys.Enter) && !prevKb.IsKeyDown(Keys.Enter))
            {
                result.Add(Types.InputHandlerResultEnd.EndMenuSelect, null);
            }
            if (kb.IsKeyDown(Keys.Escape) && !prevKb.IsKeyDown(Keys.Escape))
            {
                result.Add(Types.InputHandlerResultEnd.BackMenuSelect, null);
            }
            this.LastMouse = currMouse;
            this.prevKb = kb;
            this.prevMouse = mouse;
            return result;
        }
    }
}
